/*
 * Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.huawei.cloudapp.ui.activity;

import static com.huawei.cloudapp.utils.CasConstantsUtil.COMMON;
import static com.huawei.cloudapp.utils.CasConstantsUtil.ENCRYPT_IV;
import static com.huawei.cloudapp.utils.CasConstantsUtil.IAM_USERNAME;
import static com.huawei.cloudapp.utils.CasConstantsUtil.MANAGEMENT;
import static com.huawei.cloudapp.utils.CasConstantsUtil.PASSWORD;
import static com.huawei.cloudapp.utils.CasConstantsUtil.PROJECT_ID;
import static com.huawei.cloudapp.utils.CasConstantsUtil.REGION_NAME;
import static com.huawei.cloudapp.utils.CasConstantsUtil.SELECTED_REGION_POSITION;
import static com.huawei.cloudapp.utils.CasConstantsUtil.SESSION_ID;
import static com.huawei.cloudapp.utils.CasConstantsUtil.TOKEN;
import static com.huawei.cloudapp.utils.CasConstantsUtil.TOKEN_EXPIRE_TIME;
import static com.huawei.cloudapp.utils.CasConstantsUtil.USERNAME;
import static com.huawei.cloudapp.utils.CasConstantsUtil.USER_INFO;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import com.hjq.toast.ToastParams;
import com.hjq.toast.Toaster;
import com.hjq.toast.style.CustomToastStyle;
import com.huawei.cloudapp.R;
import com.huawei.cloudapp.common.CasRecord;
import com.huawei.cloudapp.model.IHandleData;
import com.huawei.cloudapp.model.IUserModel;
import com.huawei.cloudapp.model.bean.CustomException;
import com.huawei.cloudapp.model.bean.User;
import com.huawei.cloudapp.presenter.UserPresenter;
import com.huawei.cloudapp.ui.views.MaterialLoginView;
import com.huawei.cloudapp.utils.CasAESKeystoreUtils;
import com.huawei.cloudapp.utils.CasCommonUtils;

import java.util.HashMap;
import java.util.List;


public class CasCloudLoginActivity extends Activity implements IHandleData<User> {

    private static final String TAG = "CasCloudLoginActivity";
    private MaterialLoginView loginView;
    private CasRecord mUserRecord;
    private UserPresenter mUserPresenter;
    private IUserModel mUserModel;
    private String selectedRegion;
    private String mPass;
    private User mUser;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Toaster.init(getApplication());
        overridePendingTransition(0, 0);
        super.onCreate(savedInstanceState);
        mUserRecord = new CasRecord(getSharedPreferences(USER_INFO, MODE_PRIVATE));
        if (!CasCommonUtils.isDirectMode()) {
            selectedRegion = MANAGEMENT;
        } else {
            CasRecord mCommonRecord = new CasRecord(getSharedPreferences(COMMON, MODE_PRIVATE));
            String selectedRegionPosition = mCommonRecord.getRecord(SELECTED_REGION_POSITION);
            if (selectedRegionPosition == null || selectedRegionPosition.isEmpty() || Integer.parseInt(selectedRegionPosition) < 0) {
                selectedRegion = REGION_NAME.get(6);
            } else {
                selectedRegion = REGION_NAME.get(Integer.parseInt(selectedRegionPosition));
            }
        }
        initView();
    }

    private void initView() {
        setContentView(R.layout.activity_cas_cloud_login);
        loginView = findViewById(R.id.login);
        loginView.setIamEnable(CasCommonUtils.isDirectMode());
        loginView.setListener((loginUser, loginIamUser, loginPass, isUseIam) -> {

            String userStr = loginUser.getEditText().getText().toString();
            if (userStr.isEmpty()) {
                loginUser.setError("User name can't be empty");
                return;
            } else if (userStr.length() >32) {
                loginUser.setError("Username is invalid, length should be 1-32.");
                return;
            }
            loginUser.setError("");

            String iamUser = null;
            if (CasCommonUtils.isDirectMode()) {
                if (isUseIam) {

                    iamUser = loginIamUser.getEditText().getText().toString();
                    if (iamUser.isEmpty()) {
                        loginIamUser.setError("Iam User name can't be empty");
                        return;
                    } else if (userStr.length() >32) {
                        loginIamUser.setError("Iam Username is invalid, length should be 1-32.");
                        return;
                    }
                    loginIamUser.setError("");
                }
            }

            String pass = loginPass.getEditText().getText().toString();
            if (pass.isEmpty()) {
                loginPass.setError("Password can't be empty");
                return;
            } else if (pass.length() < 6 || pass.length() >32) {
                loginPass.setError("Password is invalid, length should be 6-32.");
                return;
            }
            loginPass.setError("");

            User user = new User(userStr, iamUser, null, null, null, "");
            if (CasCommonUtils.isDirectMode()) {
                mUserModel = new com.huawei.cloudapp.model.direct.UserModel();
            } else {
                mUserModel = new com.huawei.cloudapp.model.management.UserModel();
            }
            mUserPresenter = new UserPresenter(this, mUserModel);
            mUserPresenter.getUser(user, pass, selectedRegion);
            mPass = pass;
        });
    }

    @Override
    protected void onResume() {
        super.onResume();

        String username = mUserRecord.getRecord(USERNAME);
        if (username == null || username.isEmpty()) {
            return;
        }

        HashMap<String, String> tokens = mUserRecord.getHashMapRecord(TOKEN);
        HashMap<String, String> tokenExpireTimes = mUserRecord.getHashMapRecord(TOKEN_EXPIRE_TIME);
        if(tokens.containsKey(selectedRegion)) {
            if (!CasCommonUtils.isDirectMode()) {
                startActivity();
                return;
            }
            String userTokenExpireTime = tokenExpireTimes.get(selectedRegion);
            if (userTokenExpireTime == null || userTokenExpireTime.isEmpty()
                    || Long.parseLong(userTokenExpireTime) + 5000 < System.currentTimeMillis()) {
                getSharedPreferences(USER_INFO, MODE_PRIVATE).edit().clear().apply();
                ToastParams params = new ToastParams();
                params.text = getResources().getString(R.string.user_info_invalid_need_login);
                params.style = new CustomToastStyle(R.layout.toast_error);
                Toaster.show(params);
                return;
            }
            startActivity();
        }
    }

    private void startActivity() {
        Intent intent;
        if (CasCommonUtils.isDirectMode()) {
            intent = new Intent(CasCloudLoginActivity.this, CasCloudMainDirectActivity.class);
        } else {
            intent = new Intent(CasCloudLoginActivity.this, CasCloudMainManagementActivity.class);
        }
        startActivity(intent);
        finish();
    }
    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    public void handleData(List<User> list, int count) {
        User user = list.get(0);
        if (user == null) {
            return;
        }

        mUserRecord.setRecord(USERNAME, user.getUsername());
        mUserRecord.setRecord(IAM_USERNAME, user.getIamUsername());
        HashMap<String, String> encryptResult = CasAESKeystoreUtils.encryptData(mPass);

        CasCommonUtils.setEncryptPass(encryptResult.get(PASSWORD));
        CasCommonUtils.setEncryptIV(encryptResult.get(ENCRYPT_IV));

        HashMap<String, String> tokens = user.getUserToken();
        mUserRecord.setHashMapRecord(TOKEN, tokens);

        HashMap<String, String> tokenExpireTimes = user.getUserTokenExpireTime();
        mUserRecord.setHashMapRecord(TOKEN_EXPIRE_TIME, tokenExpireTimes);

        HashMap<String, String> projectIds = user.getUserProjectId();
        mUserRecord.setHashMapRecord(PROJECT_ID, projectIds);
        mUserRecord.setRecord(SESSION_ID, list.get(0).getUserSessionId());
        mUser = user;
        startActivity();
    }

    @Override
    public void handleError(Exception e) {
        String toastStr;
        if (e instanceof CustomException.LogInInfoErrorException) {
            toastStr = getResources().getString(R.string.failed_to_login_check_username_and_password);
        } else if (e instanceof CustomException.EmptyResponseFromServerException) {
            toastStr = getResources().getString(R.string.cas_phone_connect_server_fail_tip_message);
        } else if (e instanceof CustomException.FailedToLogInException) {
            toastStr = getResources().getString(R.string.failed_to_login);
        } else if (e instanceof CustomException.ForbiddenException) {
            toastStr = getResources().getString(R.string.no_permission);
        } else if (e instanceof CustomException.ServerError) {
            toastStr = getResources().getString(R.string.service_internal_error);
        }  else if (e instanceof CustomException.ServiceUnavailableException) {
            toastStr = getResources().getString(R.string.cas_phone_connect_server_fail_tip_message);
        } else {
            toastStr = getResources().getString(R.string.failed_to_login);
            Log.e(TAG, "handleError: ", e);
        }
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                ToastParams params = new ToastParams();
                params.text = toastStr;
                params.style = new CustomToastStyle(R.layout.toast_error);
                Toaster.show(params);
            }
        });
    }
}